package com.ruoyi.system.controller;

import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.hutool.poi.excel.BigExcelWriter;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.validate.AddGroup;
import com.ruoyi.common.core.validate.EditGroup;
import com.ruoyi.common.core.web.controller.BaseController;
import com.ruoyi.common.excel.utils.ExcelUtil;
import com.ruoyi.common.log.annotation.Log;
import com.ruoyi.common.log.enums.BusinessType;
import com.ruoyi.common.mybatis.core.page.PageQuery;
import com.ruoyi.common.satoken.utils.LoginHelper;
import com.ruoyi.system.api.model.LoginUser;
import com.ruoyi.system.domain.Investigation;
import com.ruoyi.system.domain.bo.InvestigationUserAnswerBo;
import com.ruoyi.system.domain.vo.InvestigationStatisticVo;
import com.ruoyi.system.enums.PubStatusEnum;
import com.ruoyi.system.service.IInvestigationUserAnswerService;
import com.ruoyi.system.util.ExportUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import com.ruoyi.system.domain.vo.InvestigationVo;
import com.ruoyi.system.domain.bo.InvestigationBo;
import com.ruoyi.system.service.IInvestigationService;
import com.ruoyi.common.mybatis.core.page.TableDataInfo;

import java.io.IOException;
import java.net.URLEncoder;
import java.util.List;
import java.util.Arrays;
import javax.servlet.http.HttpServletRequest;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import javax.servlet.http.HttpServletResponse;

/**
 * 问卷控制器
 * 前端访问路由地址为:/system/investigation
 *
 * @author ruoyi
 * @date 2024-12-13
 */
@Slf4j
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/investigation")
public class InvestigationController extends BaseController {

    private final IInvestigationService iInvestigationService;

    private final IInvestigationUserAnswerService answerService;

    @Value("${investigation_statistic_url}")
    private String statisticUrl;

    /**
     * 查询问卷列表
     */
    @SaCheckPermission("system:investigation:list")
    @GetMapping("/list")
    public TableDataInfo<InvestigationVo> list(InvestigationBo bo, PageQuery pageQuery) {
        return iInvestigationService.queryPageList(bo, pageQuery);
    }

    /**
     * 导出问卷列表
     */
    @SaCheckPermission("system:investigation:export")
    @Log(title = "问卷", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(InvestigationBo bo, HttpServletResponse response) {
        List<InvestigationVo> list = iInvestigationService.queryList(bo);
        ExcelUtil.exportExcel(list, "问卷", InvestigationVo.class, response);
    }

    /**
     * 获取问卷详细信息
     *
     * @param id 主键
     */
    @SaCheckPermission("system:investigation:query")
    @GetMapping("/{id}")
    public R<InvestigationVo> getInfo(@NotNull(message = "主键不能为空") @PathVariable Long id) {
        return R.ok(iInvestigationService.queryById(id));
    }

    /**
     * 新增问卷
     */
    @SaCheckPermission("system:investigation:add")
    @Log(title = "问卷", businessType = BusinessType.INSERT)
    @PostMapping()
    public R<Void> add(@Validated(AddGroup.class) @RequestBody InvestigationBo bo) {
        return toAjax(iInvestigationService.insertByBo(bo));
    }

    /**
     * 发布
     */
    @SaCheckPermission("system:investigation:online")
    @Log(title = "问卷上线", businessType = BusinessType.UPDATE)
    @PostMapping("/online/{id}")
    public R<Void> publish(@NotNull(message = "主键不能为空") @PathVariable Long id) {
        return toAjax(iInvestigationService.updateStatus(id, PubStatusEnum.PUBLISHED.getValue()));
    }

    /**
     * 取消发布
     */
    @SaCheckPermission("system:investigation:offline")
    @Log(title = "问卷下线", businessType = BusinessType.UPDATE)
    @PostMapping("/offline/{id}")
    public R<Void> unPublish(@NotNull(message = "主键不能为空") @PathVariable Long id) {
        return toAjax(iInvestigationService.updateStatus(id, PubStatusEnum.NOT_PUBLISH.getValue()));
    }

    /**
     * 新增问卷回答
     */
    @SaCheckPermission("system:investigationAnswer:answer")
    @Log(title = "回答问卷", businessType = BusinessType.INSERT)
    @PostMapping("/answer/{investigationId}")
    public R<Void> userAnswer(@NotNull(message = "问卷不能为空") @PathVariable Long investigationId,
                              @NotEmpty(message = "答案不能为空") @Validated({AddGroup.class, EditGroup.class}) @RequestBody List<InvestigationUserAnswerBo> bos) {
        boolean ok = answerService.insertByBos(investigationId, LoginHelper.getUserId(), bos);
        if (ok) {
            iInvestigationService.incAnswerCount(investigationId);
        }
        return toAjax(ok);
    }

    /**
     * 修改问卷
     */
    @SaCheckPermission("system:investigation:edit")
    @Log(title = "问卷", businessType = BusinessType.UPDATE)
    @PutMapping()
    public R<Void> edit(@Validated(EditGroup.class) @RequestBody InvestigationBo bo) {
        return toAjax(iInvestigationService.updateByBo(bo));
    }

    /**
     * 删除问卷
     *
     * @param ids 主键串
     */
    @SaCheckPermission("system:investigation:remove")
    @Log(title = "问卷", businessType = BusinessType.DELETE)
    @DeleteMapping("/{ids}")
    public R<Void> remove(@NotEmpty(message = "主键不能为空") @PathVariable Long[] ids) {
        return toAjax(iInvestigationService.deleteWithValidByIds(Arrays.asList(ids), true));
    }

    @SaCheckPermission("system:investigation:edit")
    @GetMapping("/statistic/{id}")
    public R<InvestigationStatisticVo> statistic(@NotNull(message = "问卷不能为空") @PathVariable Long id) {
        return R.ok(iInvestigationService.statistic(id));
    }

    @SaCheckPermission("system:investigation:edit")
    @GetMapping("/statistic/export/{id}")
    public void statisticExport(@NotNull(message = "问卷不能为空") @PathVariable Long id, HttpServletRequest request,
                          HttpServletResponse response) throws Exception {
        InvestigationVo investigation = iInvestigationService.queryById(id, true);
        String url = String.format("%s?id=%d&Authorization=%s", statisticUrl, id, request.getHeader("Authorization").split(" ")[1]);
        log.info(url);
        String tmpFile = "/tmp/" + id;
        ExportUtil.exportPdf(url, "chartReady", tmpFile, investigation.getName() + "统计", response);
    }

    @SaCheckPermission("system:investigation:edit")
    @GetMapping("/answer/export/{investigationId}")
    public void answerExport(@NotNull(message = "问卷不能为空") @PathVariable Long investigationId, HttpServletResponse response) throws IOException {
        InvestigationVo investigation = iInvestigationService.queryById(investigationId, true);
        List list = iInvestigationService.getAnswerExport(investigation);

        BigExcelWriter excelWriter = new BigExcelWriter();
        excelWriter.write(list);

        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8");
        response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(investigation.getName() + "回答明细", "utf-8") + ".xlsx");
        excelWriter.flush(response.getOutputStream(), true);
        excelWriter.close();
    }
}
